// wxWidgets
#include <wx/aboutdlg.h>

#include "AssistantFrame.h"

#include <cmath>
#include <vector>
#include <algorithm>

#include <wx/msgdlg.h>
#include <wx/textdlg.h>
#include <wx/arrstr.h>
#include <wx/propgrid/propgrid.h>
#include <wx/stdpaths.h>
#include <wx/file.h>
#include <wx/datetime.h>
#include <wx/dirdlg.h>
#include <wx/filedlg.h>

AssistantFrame::AssistantFrame( wxWindow* parent )
:
AssistantFrameBase( parent ),
m_filePath( wxStandardPaths::Get().GetUserDataDir() ),
m_categories()
{
	int widthsArray [3] = {-1, -1, 150};
	m_statusBar->SetStatusWidths( 3, widthsArray );
	m_statusBar->SetStatusText( wxT("Welcome to DoG Assistant"), 0 );

	m_generatedReport->SetReadOnly( true );

	LoadSettingsFromFile();

	m_grid->AutoSize();
	m_grid->Update();
	m_grid->Refresh();
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAppClose( wxCloseEvent& )
{
	wxCommandEvent cmdEvent;
	OnExit( cmdEvent );
}
void AssistantFrame::OnExit( wxCommandEvent& /*event*/ )
{
	SaveSettingsToFile();
	Destroy();
}

void AssistantFrame::OnSaveForm( wxCommandEvent& )
{
	bool saved = SaveSettingsToFile();
	if( saved )
	{
		wxMessageBox( wxT( "Save Successful" ), wxT( "Information" ), wxICON_INFORMATION );
	}
	else
	{
		wxMessageBox( wxT( "Save Not Successful" ), wxT( "Warning" ), wxICON_ERROR );
	}
}

void AssistantFrame::OnAbout( wxCommandEvent& /*event*/ )
{
	wxAboutDialogInfo info;
    info.SetName( wxT("Assistant") );
	info.AddDeveloper( wxT( "Andrew J. Walter" ) );
	info.SetLicense( wxT("MIT") );
    info.SetVersion( wxT("0.01") );
	info.SetIcon( this->GetIcon() );
	info.SetWebSite( wxT("http://code.google.com/p/leadership-assistant") );
    info.SetDescription( wxT("Assistant is used to make accessing items required from leadership easier.") );
    info.SetCopyright( wxT("Copyright (c) Disciples of Gaming 2012") );
	info.AddArtist( wxT( "Icons from famfamfam" ) );
	info.AddArtist( wxT( "http://www.xbox.com" ) );
	info.AddArtist( wxT("http://halo.xbox.com") );
	info.AddArtist( wxT("http://www.photobucket.com") );
	info.AddArtist( wxT("http://www.facebook.com") );

    wxAboutBox( info );
}

void AssistantFrame::OnHelpReportBug( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://code.google.com/p/leadership-assistant/issues/entry" ) );
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnDoGRoster( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "https://dogroster.appspot.com/" ) );
}

void AssistantFrame::OnForums( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://www.disciplesofgaming.com/forum" ) );
}

void AssistantFrame::OnXboxLive( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://www.xbox.com/" ) );
}

void AssistantFrame::OnGamertagLookup( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://www.xboxgamertag.com/" ) );
}

void AssistantFrame::OnPhotobucket( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://s1232.photobucket.com/profile/Disciples_of_Gaming" ) );
}

void AssistantFrame::OnCallOfDutyElite( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://www.callofduty.com/elite" ) );
}

void AssistantFrame::OnHaloWaypoint( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://halo.xbox.com/" ) );
}

void AssistantFrame::OnFacebook( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://www.facebook.com/groups/98668706297/" ) );
}

void AssistantFrame::OnDoGMachinima( wxCommandEvent& )
{
	wxLaunchDefaultBrowser( wxT( "http://www.youtube.com/user/DoGmachinima" ) );
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAddCategory( wxCommandEvent& )
{
	wxString name = wxGetTextFromUser( wxT( "Please Enter the Category Name" ), wxT( "Name Entry" ) );
	if( !name.StartsWith( wxT(" ") ) )
	{
		AddUsernamePasswordCategoryToPropertyGrid( name );
		m_usernamePasswordPropertyGrid->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
}

void AssistantFrame::OnRemoveCategory( wxCommandEvent& )
{
	wxPGId selectedProperty = m_usernamePasswordPropertyGrid->GetSelectedProperty();
	wxString selectedPropertyName = selectedProperty.GetName();

	if( selectedPropertyName.Contains( wxT( "Username" ) ) )
	{
		selectedPropertyName.Replace( wxT( " Username" ), wxT( "" ) );
	}
	else if( selectedPropertyName.Contains( wxT( "Password" ) ) )
	{
		selectedPropertyName.Replace( wxT( " Password" ), wxT( "" ) );
	}

	wxPGId category = m_usernamePasswordPropertyGrid->GetFirstCategory();

	while( category )
	{
		if( category.GetName() == selectedPropertyName )
		{
			break;
		}

		category = m_usernamePasswordPropertyGrid->GetNextCategory( category );
	}

	for( std::vector< wxString >::iterator it = m_categories.begin(); it < m_categories.end(); ++it )
	{
		if( *it == selectedPropertyName )
		{
			m_categories.erase( it );
			break;
		}
	}
	m_usernamePasswordPropertyGrid->Delete( category );
	m_usernamePasswordPropertyGrid->Refresh();
}

void AssistantFrame::AddUsernamePasswordCategoryToPropertyGrid( const wxString& name, const wxString& usernameValue, const wxString& passwordValue )
{
	wxPGId category = m_usernamePasswordPropertyGrid->AppendCategory( name, name );
	
	m_usernamePasswordPropertyGrid->Append( wxStringProperty( name + wxT( " Username" ), wxPG_LABEL, usernameValue ) );
	m_usernamePasswordPropertyGrid->Append( wxStringProperty( name + wxT( " Password" ), wxPG_LABEL, passwordValue ) );

	m_categories.push_back( name );
}

void AssistantFrame::PopulateDefaultUsernamePasswordPropertyGrid()
{
	AddUsernamePasswordCategoryToPropertyGrid( wxT( "DoG Forums" ) );
	AddUsernamePasswordCategoryToPropertyGrid( wxT( "DoG Appspot" ) );
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAddNameToList( wxCommandEvent& )
{
	wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag/Team Name" ), wxT( "Name Entry" ) );
	if( !name.StartsWith( wxT(" ") ) )
	{
		wxArrayString names;
		names.Add( name );
		m_nameList->InsertItems( names, m_nameList->GetCount() );
	}
	else
	{
		wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
}

void AssistantFrame::OnRemoveNameFromList( wxCommandEvent& )
{
	wxArrayInt selections;
	m_nameList->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_nameList->Delete( selections[ count ] );
		}
		m_nameList->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot delete, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnEditName( wxCommandEvent& )
{
	wxArrayInt selections;
	m_nameList->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag/Team Name" ), wxT( "Name Entry" ) );
		wxArrayString names;
		if( !name.StartsWith( wxT(" ") ) )
		{
			names.Add( name );
		}
		else
		{
			wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
			return;
		}
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_nameList->Delete( selections[ count ] );
		}
		m_nameList->InsertItems( names, selections.Item(0) );
		m_nameList->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot edit, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnRemoveAllNames( wxCommandEvent& )
{
	if( m_nameList->GetCount() > 0 )
	{
		int answer = wxMessageBox( wxT( "Remove all names from list?" ), wxT( "Confirm" ), wxYES_NO | wxICON_QUESTION);
		if (answer == wxYES)
		{
			m_nameList->Clear();
		}
		else
		{
			return;
		}
	}
	else
	{
		return;
	}
}

void AssistantFrame::OnSingleEliminationClicked( wxCommandEvent& )
{
	double n;
	n = m_nameList->GetCount();
	if( n<4 )
	{
		wxMessageBox( wxT("Not enough people for a Single Elimination Tournament.\nAdd more people/teams to the list then generate again."), wxT("Single Elimination"), wxOK | wxICON_INFORMATION );
		return;
	}

	if( ( m_grid->GetNumberCols() != 0 ) && ( m_grid->GetNumberRows() != 0 ) )
	{
		m_grid->ClearGrid(); 
		m_grid->DeleteCols( 0, m_grid->GetNumberCols() );
		m_grid->DeleteRows( 0, m_grid->GetNumberRows() );
	}

	if( (fmod( n, 2 ) == 0 ) )
	{		
		wxArrayString names = m_nameList->GetStrings();
		std::vector< wxString > namesStd;
		for( unsigned int i = 0; i < names.size(); ++i ) 
		{
			namesStd.push_back( names.Item( i ) );
		}

		for( unsigned int i = 0; i < names.size(); ++i )
		{
			std::random_shuffle( namesStd.begin(), namesStd.end() );
		}
		int numMatches = n/2;
		m_grid->InsertRows(0, 2);
		m_grid->SetRowLabelValue( 0, wxT( "Opponent 1" ) );
		m_grid->SetRowLabelValue( 1, wxT( "Opponent 2" ) );
		m_grid->InsertCols(0, numMatches);
		for( int i = 0; i < numMatches; ++i )
		{
			wxString label;
			label.Printf( wxT( "Match %d" ), i+1 );
			m_grid->SetColLabelValue( i, label );
			m_grid->SetCellValue( 0, i, namesStd.back() );
			namesStd.pop_back();
			m_grid->SetCellValue( 1, i, namesStd.back() );
			namesStd.pop_back();
		}
	}
	else
	{
		double modifiedn = n;
		while( modifiedn >= 0 )
		{
			modifiedn = modifiedn - 1;
			if( (fmod( modifiedn, 2 ) == 0 ) )
			{
				break;
			}
		}
		wxArrayString names = m_nameList->GetStrings();
		std::vector< wxString > namesStd;
		for( unsigned int i = 0; i < names.size(); ++i ) 
		{
			namesStd.push_back( names.Item( i ) );
		}

		for( unsigned int i = 0; i < names.size(); ++i )
		{
			std::random_shuffle( namesStd.begin(), namesStd.end() );
		}
		int numMatches = modifiedn/2;
		m_grid->InsertRows(0, 2);
		m_grid->SetRowLabelValue( 0, wxT( "Opponent 1" ) );
		m_grid->SetRowLabelValue( 1, wxT( "Opponent 2" ) );
		m_grid->InsertCols(0, numMatches);
		for( int i = 0; i < numMatches; ++i )
		{
			wxString label;
			label.Printf( wxT( "Match %d" ), i+1 );
			m_grid->SetColLabelValue( i, label );
			m_grid->SetCellValue( 0, i, namesStd.back() );
			namesStd.pop_back();
			m_grid->SetCellValue( 1, i, namesStd.back() );
			namesStd.pop_back();
		}
		for( unsigned int i = 0; i < namesStd.size(); ++i )
		{
			m_grid->InsertCols( m_grid->GetNumberCols() + i, 1);
			m_grid->SetColLabelValue( m_grid->GetNumberCols() + i - 1, wxT( "Bye" ) );
			m_grid->SetCellValue( 0, m_grid->GetNumberCols() + i - 1, namesStd.back() );
			namesStd.pop_back();
		}
	}
	m_grid->AutoSize();
	m_grid->Update();
	m_grid->Refresh();
}

void AssistantFrame::OnRoundRobinClicked( wxCommandEvent& )
{
	double n;
	n = m_nameList->GetCount();
	if( n<4 )
	{
		wxMessageBox( wxT("Not enough people for a Round Robin Tournament.\nAdd more people/teams to the list then generate again."), wxT("Round Robin"), wxOK | wxICON_INFORMATION );
		return;
	}

	if( ( m_grid->GetNumberCols() != 0 ) && ( m_grid->GetNumberRows() != 0 ) )
	{
		m_grid->ClearGrid(); 
		m_grid->DeleteCols( 0, m_grid->GetNumberCols() );
		m_grid->DeleteRows( 0, m_grid->GetNumberRows() );
	}
	
	wxArrayString names = m_nameList->GetStrings();
	std::vector< wxString > namesStd;
	for( unsigned int i = 0; i < names.size(); ++i ) 
	{
		namesStd.push_back( names.Item( i ) );
	}
	if( (fmod( n, 2 ) != 0 ) )
	{
		namesStd.push_back( wxT( "Bye" ) );
	}
	
	n=namesStd.size();

	for( unsigned int i = 0; i < namesStd.size(); ++i )
	{
		std::random_shuffle( namesStd.begin(), namesStd.end() );
	}

	int numRounds = n-1;
	int numMatches = n/2;
	for( int i = 0; i < numRounds; ++i )
	{
		m_grid->InsertCols(i, 1);
		wxString label;
		label.Printf( wxT( "Round %d" ), i+1 );
		m_grid->SetColLabelValue( i, label );
	}

	for( int i = 0; i < numMatches; ++i )
	{
		m_grid->InsertRows(i*2, 2);
		wxString label;
		label.Printf( wxT( "Match %d" ), i+1 );
		m_grid->SetRowLabelValue( i*2, label );
		m_grid->SetRowLabelValue( (i*2)+1, label );
	}
	wxString constantTeam = namesStd.back();
	namesStd.pop_back();
		
	for( int i = 0; i < numRounds; ++i )
	{
		m_grid->SetCellValue( constantTeam, 0, i );
	}

	int end = namesStd.size()-1;

	for( int i = 0; i < numRounds; i++ )
	{
		if( i != 0 )
		{
			std::rotate( namesStd.begin(), namesStd.end()-1, namesStd.end() );
		}

		int evenRowPos = 0;
		int oddRowPos = 0;
		for( int j = 0; j < numRounds; ++j )
		{
			double rowPos = j + 1;
			if( (fmod( rowPos, 2 ) == 0 ) )
			{
				m_grid->SetCellValue( namesStd.at( 0+evenRowPos ), rowPos, i );
				evenRowPos++;
			}
			else
			{
				m_grid->SetCellValue( namesStd.at( end-oddRowPos ), rowPos, i );
				oddRowPos++;
			}
		}		
	}
	m_grid->AutoSize();
	m_grid->Update();
	m_grid->Refresh();
}

void AssistantFrame::OnClearGrid( wxCommandEvent& )
{
	int answer = wxMessageBox( wxT( "Clear Grid?" ), wxT( "Confirm" ), wxYES_NO | wxICON_QUESTION);
	if (answer == wxYES)
	{
		if( ( m_grid->GetNumberCols() != 0 ) && ( m_grid->GetNumberRows() != 0 ) )
		{
			m_grid->ClearGrid(); 
			m_grid->DeleteCols( 0, m_grid->GetNumberCols() );
			m_grid->DeleteRows( 0, m_grid->GetNumberRows() );
		}
	}
	else
	{
		return;
	}
	m_grid->AutoSize();
	m_grid->Update();
	m_grid->Refresh();
}

void AssistantFrame::OnTournamentCreatorSashChanged( wxSplitterEvent& event )
{
	m_splitter1->SetSashPosition( event.GetSashPosition(), true );
	m_mainPanelBase->Layout();
	m_mainPanelBase->Update();
	m_mainPanelBase->Refresh();

	m_grid->AutoSize();
	m_grid->Update();
	m_grid->Refresh();
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAddLieutenant( wxCommandEvent& )
{
	wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
	if( !name.StartsWith( wxT(" ") ) )
	{
		wxArrayString names;
		names.Add( name );
		m_lieutenantListBox->InsertItems( names, m_lieutenantListBox->GetCount() );
	}
	else
	{
		wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
}

void AssistantFrame::OnRemoveLieutenant( wxCommandEvent& )
{
	wxArrayInt selections;
	m_lieutenantListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_lieutenantListBox->Delete( selections[ count ] );
		}
		m_lieutenantListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot delete, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnEditLieutenant( wxCommandEvent& )
{
	wxArrayInt selections;
	m_lieutenantListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
		wxArrayString names;
		if( !name.StartsWith( wxT(" ") ) )
		{
			names.Add( name );
		}
		else
		{
			wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
			return;
		}
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_lieutenantListBox->Delete( selections[ count ] );
		}
		m_lieutenantListBox->InsertItems( names, selections.Item(0) );
		m_lieutenantListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot edit, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnClearLieutenantList( wxCommandEvent& )
{
	if( m_lieutenantListBox->GetCount() > 0 )
	{
		int answer = wxMessageBox( wxT( "Remove all names from list?" ), wxT( "Confirm" ), wxYES_NO | wxICON_QUESTION);
		if (answer == wxYES)
		{
			m_lieutenantListBox->Clear();
		}
		else
		{
			return;
		}
	}
	else
	{
		return;
	}
}


//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAddMSGT( wxCommandEvent& )
{
	wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
	if( !name.StartsWith( wxT(" ") ) )
	{
		wxArrayString names;
		names.Add( name );
		m_msgtListBox->InsertItems( names, m_msgtListBox->GetCount() );
	}
	else
	{
		wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
}

void AssistantFrame::OnRemoveMSGT( wxCommandEvent& )
{
	wxArrayInt selections;
	m_msgtListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_msgtListBox->Delete( selections[ count ] );
		}
		m_msgtListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot delete, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnEditMSGT( wxCommandEvent& )
{
	wxArrayInt selections;
	m_msgtListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
		wxArrayString names;
		if( !name.StartsWith( wxT(" ") ) )
		{
			names.Add( name );
		}
		else
		{
			wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
			return;
		}
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_msgtListBox->Delete( selections[ count ] );
		}
		m_msgtListBox->InsertItems( names, selections.Item(0) );
		m_msgtListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot edit, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnClearMSGTList( wxCommandEvent& )
{
	if( m_msgtListBox->GetCount() > 0 )
	{
		int answer = wxMessageBox( wxT( "Remove all names from list?" ), wxT( "Confirm" ), wxYES_NO | wxICON_QUESTION);
		if (answer == wxYES)
		{
			m_msgtListBox->Clear();
		}
		else
		{
			return;
		}
	}
	else
	{
		return;
	}
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAddSergeant( wxCommandEvent& )
{
	wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
	if( !name.StartsWith( wxT(" ") ) )
	{
		wxArrayString names;
		names.Add( name );
		m_sergeantListBox->InsertItems( names, m_sergeantListBox->GetCount() );
	}
	else
	{
		wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
}

void AssistantFrame::OnRemoveSergeant( wxCommandEvent& )
{
	wxArrayInt selections;
	m_sergeantListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_sergeantListBox->Delete( selections[ count ] );
		}
		m_sergeantListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot delete, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnEditSergeant( wxCommandEvent& )
{
	wxArrayInt selections;
	m_sergeantListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
		wxArrayString names;
		if( !name.StartsWith( wxT(" ") ) )
		{
			names.Add( name );
		}
		else
		{
			wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
			return;
		}
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_sergeantListBox->Delete( selections[ count ] );
		}
		m_sergeantListBox->InsertItems( names, selections.Item(0) );
		m_sergeantListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot edit, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnClearSergeantList( wxCommandEvent& )
{
	if( m_sergeantListBox->GetCount() > 0 )
	{
		int answer = wxMessageBox( wxT( "Remove all names from list?" ), wxT( "Confirm" ), wxYES_NO | wxICON_QUESTION);
		if (answer == wxYES)
		{
			m_sergeantListBox->Clear();
		}
		else
		{
			return;
		}
	}
	else
	{
		return;
	}
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAddDoGTag( wxCommandEvent& )
{
	wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
	if( !name.StartsWith( wxT(" ") ) )
	{
		wxArrayString names;
		names.Add( name );
		m_dogTagListBox->InsertItems( names, m_dogTagListBox->GetCount() );
	}
	else
	{
		wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
}

void AssistantFrame::OnRemoveDoGTag( wxCommandEvent& )
{
	wxArrayInt selections;
	m_dogTagListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_dogTagListBox->Delete( selections[ count ] );
		}
		m_dogTagListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot delete, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnEditDoGTag( wxCommandEvent& )
{
	wxArrayInt selections;
	m_dogTagListBox->GetSelections( selections );
	if( !selections.IsEmpty() )
	{
		wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
		wxArrayString names;
		if( !name.StartsWith( wxT(" ") ) )
		{
			names.Add( name );
		}
		else
		{
			wxMessageBox( wxT( "Name cannot begin with a space.\nNothing will be added to the list." ), wxT( "Warning" ), wxICON_EXCLAMATION );
			return;
		}
		for( unsigned int count = 0; count < (selections.GetCount() + 1); ++count )
		{
			m_dogTagListBox->Delete( selections[ count ] );
		}
		m_dogTagListBox->InsertItems( names, selections.Item(0) );
		m_dogTagListBox->Refresh();
	}
	else
	{
		wxMessageBox( wxT( "Cannot edit, nothing was selected!" ), wxT( "Warning" ), wxICON_EXCLAMATION );
	}
	selections.clear();
}

void AssistantFrame::OnClearDoGTagList( wxCommandEvent& )
{
	if( m_dogTagListBox->GetCount() > 0 )
	{
		int answer = wxMessageBox( wxT( "Remove all names from list?" ), wxT( "Confirm" ), wxYES_NO | wxICON_QUESTION);
		if (answer == wxYES)
		{
			m_dogTagListBox->Clear();
		}
		else
		{
			return;
		}
	}
	else
	{
		return;
	}
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::OnAddMovement( wxCommandEvent& )
{
	wxString selection = m_movementChoice->GetStringSelection();
	
	wxString name = wxGetTextFromUser( wxT( "Please Enter the Gamertag" ), wxT( "Name Entry" ) );
	wxString date = wxGetTextFromUser( wxT( "Please Enter the Date (YYYY-MM-DD) of Removal/Ban/Transfer" ), wxT( "Name Entry" ) );
	wxString by = wxGetTextFromUser( wxT( "Please Enter the Approver of the Removal/Ban/Transfer" ), wxT( "Name Entry" ) );
	wxString reason = wxGetTextFromUser( wxT( "Please Enter the Reason for Removal/Ban or Transfer Branch" ), wxT( "Name Entry" ) );

	wxString combined = name + wxT( " / " ) + date + wxT( " / " ) + by + wxT( " / " ) + reason;

	if( selection == wxT( "Ban" ) )
	{
		wxArrayString names;
		names.Add( combined );
		m_banListBox->InsertItems( names, m_banListBox->GetCount() );
	}
	else if( selection == wxT( "Removal" ) )
	{
		wxArrayString names;
		names.Add( combined );
		m_removalListBox->InsertItems( names, m_removalListBox->GetCount() );
	}
	else if( selection == wxT( "Transfer" ) )
	{
		wxArrayString names;
		names.Add( combined );
		m_transfersListBox->InsertItems( names, m_transfersListBox->GetCount() );
	}
}


void AssistantFrame::OnGenerateReport( wxCommandEvent& )
{
	wxString report;

	report = report + wxT( "Branch:  DoG " ) + m_branchName->GetValue() + wxT( "\n" );

	wxString yearString;
	yearString << wxDateTime::GetCurrentYear();
	wxString monthString = wxDateTime::GetMonthName( wxDateTime::GetCurrentMonth() );
	report = report + wxT( "Report For:  " ) + monthString + wxT( ", " ) + yearString + wxT( "\n" );

	report = report + wxT( "Presented By:  " ) + m_reportBy->GetValue() + wxT( "\n" );

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][size=6][u][b]Leadership Overview[/color][/b][/u][/size]\n" );

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b]LT[/color][/b][/u]\n" );
	for ( unsigned int i = 0; i < m_lieutenantListBox->GetCount(); ++i )
	{
		wxString name = m_lieutenantListBox->GetString( i );
		report = report + name + wxT( "\n" );
	}

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b]MSGT[/color][/b][/u]\n" );
	for ( unsigned int i = 0; i < m_msgtListBox->GetCount(); ++i )
	{
		wxString name = m_msgtListBox->GetString( i );
		report = report + name + wxT( "\n" );
	}

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b]SGT[/color][/b][/u]\n" );
	for ( unsigned int i = 0; i < m_msgtListBox->GetCount(); ++i )
	{
		wxString name = m_msgtListBox->GetString( i );
		report = report + name + wxT( "\n" );
	}

	report = report + wxT( "\n" );
	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b]Member Removals (" ) + monthString + wxT( ")[/color][/b][/u]\n" );
	for ( unsigned int i = 0; i < m_removalListBox->GetCount(); ++i )
	{
		wxString name = m_removalListBox->GetString( i );
		report = report + name + wxT( "\n" );
	}

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b]Member Bannings (" ) + monthString + wxT( ")[/color][/b][/u]\n" );
	for ( unsigned int i = 0; i < m_banListBox->GetCount(); ++i )
	{
		wxString name = m_banListBox->GetString( i );
		report = report + name + wxT( "\n" );
	}

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b]Member Transfers (" ) + monthString + wxT( ")[/color][/b][/u]\n" );
	for ( unsigned int i = 0; i < m_transfersListBox->GetCount(); ++i )
	{
		wxString name = m_transfersListBox->GetString( i );
		report = report + name + wxT( "\n" );
	}

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b]New DoG Tags (" ) + monthString + wxT( ")[/color][/b][/u]\n" );
	for ( unsigned int i = 0; i < m_dogTagListBox->GetCount(); ++i )
	{
		wxString name = m_dogTagListBox->GetString( i );
		report = report + name + wxT( "\n" );
	}

	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][size=6][u][b]Monthly Recap:[/color][/b][/u][/size]\n" );
	report = report + m_recap->GetText();

	report = report + wxT( "\n" );
	report = report + wxT( "\n" );

	report = report + wxT( "[color=#FF0000][u][b][size=6]Goals for next Month:[/color][/size][/b][/u]\n" );
	report = report + m_goals->GetText();

	m_generatedReport->SetReadOnly( false );
	m_generatedReport->SetText( report );
	m_generatedReport->SetReadOnly( true );

	wxMessageBox( wxT( "Your Report was Generated Successfully!\nIt is available in the Generated Report Tab." ), wxT( "Information" ), wxICON_INFORMATION );
}

//-------------------------------------------------------------------------------------------------------------------------------------------//

void AssistantFrame::LoadSettingsFromFile()
{
	if( wxFileName::DirExists( m_filePath ) )
	{
		if( wxFileName::FileExists( m_filePath + wxT( "/settings.xml" ) ) )
		{
			wxFile settingsFile( m_filePath + wxT( "/settings.xml" ) );
			if( settingsFile.Length() != 0 )
			{
				wxXmlDocument settings;
				settings.Load( m_filePath + wxT( "/settings.xml" ) );

				if( !settings.IsOk() )
				{
					return;
				}
				wxXmlNode* root = settings.GetRoot();
				wxXmlNode* child = root->GetChildren();
				while( child )
				{
					wxString childNodeName = child->GetName();
					if ( 0 == childNodeName.CmpNoCase( wxT("app") ) )
					{
						wxXmlNode* childChild = child->GetChildren();
						while ( childChild )
						{
							// Process the items in <app>.
							wxString childChildNodeName = childChild->GetName();
							if ( 0 == childChildNodeName.CmpNoCase( wxT("propgrid") ) )
							{
								// Process items in <propgrid>.
								wxXmlNode* childChildChild = childChild->GetChildren();
								while ( childChildChild )
								{
									wxString childChildChildNodeName = childChildChild->GetName();
									wxString username = childChildChild->GetPropVal( wxT( "username" ), wxT( "default" ) );
									wxString password = childChildChild->GetPropVal( wxT( "password" ), wxT( "default" ) );

									childChildChildNodeName.Replace( wxT( "_" ), wxT( " " ) );
									AddUsernamePasswordCategoryToPropertyGrid( childChildChildNodeName, username, password );

									childChildChild = childChildChild->GetNext();
								}
								
							}
							else if ( 0 == childChildNodeName.CmpNoCase( wxT("notes") ) )
							{
								wxString notes = childChild->GetPropVal( wxT( "value" ), wxT( "default" ) );
								m_notes->SetText( notes );
							}

							childChild = childChild->GetNext();
						}
					}
					child = child->GetNext();
				}
			}
		}
		else
		{
			PopulateDefaultUsernamePasswordPropertyGrid();
		}
	}
	else
	{
		if( !wxFileName::DirExists( m_filePath ) )
		{
			wxFileName::Mkdir( m_filePath, 777, wxPATH_MKDIR_FULL );
		}

		PopulateDefaultUsernamePasswordPropertyGrid();
	}
}

bool AssistantFrame::SaveSettingsToFile()
{
	bool saved = false;
	if( wxFileName::DirExists( m_filePath ) )
	{
		wxXmlDocument settings;
		wxXmlNode* rootNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxTheApp->GetAppName() + wxT("Settings"), wxEmptyString );
		
		wxXmlNode* appNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("app"), wxEmptyString );	

			wxXmlNode* propGridNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("propgrid"), wxEmptyString );
							
				for( std::vector< wxString >::iterator it = m_categories.begin(); it < m_categories.end(); ++it )
				{
					wxString name = *it;
					name.Replace( wxT( " " ), wxT( "_" ) );
					wxXmlNode* categoryNode = new wxXmlNode( wxXML_ELEMENT_NODE, name, wxEmptyString );
					categoryNode->AddProperty( wxT( "username" ), m_usernamePasswordPropertyGrid->GetPropertyValue( *it + wxT( " Username" ) ) );
					categoryNode->AddProperty( wxT( "password" ), m_usernamePasswordPropertyGrid->GetPropertyValue( *it + wxT( " Password" ) ) );
					propGridNode->AddChild( categoryNode );
				}

			appNode->AddChild( propGridNode );

			wxXmlNode* notesNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("notes"), wxEmptyString );
				notesNode->AddProperty( wxT( "value" ), m_notes->GetText() );

			appNode->AddChild( notesNode );

		rootNode->AddChild( appNode );

		settings.SetRoot( rootNode );

		if( settings.IsOk() )
		{
			// Save the created doc.
			settings.Save( m_filePath + wxT( "/settings.xml" ) );
			saved = true;
		}
	}

	return saved;
}


void AssistantFrame::OnLoadReport( wxCommandEvent& )
{

}

void AssistantFrame::OnSaveReport( wxCommandEvent& )
{
	wxFileDialog* fileDialog = new wxFileDialog( this, wxT( "Choose a Location to Save the template" ), wxT( "C:/" ), wxEmptyString, wxT( "DOGTMP files (*.dogtmp)|*.dogtmp" ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
	wxString path;
	if( fileDialog->ShowModal() == wxID_OK )
	{
		path = fileDialog->GetPath();
	}
	else
	{
		return;
	}

	wxXmlDocument settings;
	wxXmlNode* rootNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxTheApp->GetAppName() + wxT("Settings"), wxEmptyString );
		
	wxXmlNode* appNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("app"), wxEmptyString );	

		wxXmlNode* reportAndLeadershipNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("reportAndLeadership"), wxEmptyString );
							
			wxXmlNode* reportInfoNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("reportInfo"), wxEmptyString );
			reportInfoNode->AddProperty( wxT( "branchName" ), m_branchName->GetValue() );
			reportInfoNode->AddProperty( wxT( "reportBy" ), m_reportBy->GetValue() );
			reportAndLeadershipNode->AddChild( reportInfoNode );

			wxXmlNode* leadershipInfoNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("leadershipInfo"), wxEmptyString );

				wxXmlNode* LTNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("lt"), wxEmptyString );
				for( int i = 0; i < m_lieutenantListBox->GetCount(); ++i )
				{
					wxString iString;
					iString << i;
					wxXmlNode* values = new wxXmlNode( wxXML_ELEMENT_NODE, wxT( "LT" ) + iString, wxEmptyString );
					values->AddProperty( wxT( "value" ), m_lieutenantListBox->GetString( i ) );
					LTNode->AddChild( values );
				}
				leadershipInfoNode->AddChild( LTNode );

				//---------------------------------------------------------------------------------------------------------//

				wxXmlNode* MSGTNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("msgt"), wxEmptyString );
				for( int i = 0; i < m_msgtListBox->GetCount(); ++i )
				{
					wxString iString;
					iString << i;
					wxXmlNode* values = new wxXmlNode( wxXML_ELEMENT_NODE, wxT( "MSGT" ) + iString, wxEmptyString );
					values->AddProperty( wxT( "value" ), m_msgtListBox->GetString( i ) );
					MSGTNode->AddChild( values );
				}
				leadershipInfoNode->AddChild( MSGTNode );

				//---------------------------------------------------------------------------------------------------------//

				wxXmlNode* SGTNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("sgt"), wxEmptyString );
				for( int i = 0; i < m_sergeantListBox->GetCount(); ++i )
				{
					wxString iString;
					iString << i;
					wxXmlNode* values = new wxXmlNode( wxXML_ELEMENT_NODE, wxT( "SGT" ) + iString, wxEmptyString );
					values->AddProperty( wxT( "value" ), m_sergeantListBox->GetString( i ) );
					SGTNode->AddChild( values );
				}
				leadershipInfoNode->AddChild( SGTNode );

				//---------------------------------------------------------------------------------------------------------//

				wxXmlNode* TagNode = new wxXmlNode( wxXML_ELEMENT_NODE, wxT("tags"), wxEmptyString );
				for( int i = 0; i < m_dogTagListBox->GetCount(); ++i )
				{
					wxString iString;
					iString << i;
					wxXmlNode* values = new wxXmlNode( wxXML_ELEMENT_NODE, wxT( "LT" ) + iString, wxEmptyString );
					values->AddProperty( wxT( "value" ), m_dogTagListBox->GetString( i ) );
					TagNode->AddChild( values );
				}
				leadershipInfoNode->AddChild( TagNode );

			reportAndLeadershipNode->AddChild( leadershipInfoNode );

		appNode->AddChild( reportAndLeadershipNode );

	rootNode->AddChild( appNode );

	settings.SetRoot( rootNode );

	if( settings.IsOk() )
	{
		// Save the created doc.
		settings.Save( path );
	}
	
}
